exprY(TSh,Etqh,Etq,Programah,Programa) -->
        termino(TSh,Etqh,Etq1,Programah,Programa1), 
        opSuma(Op),
        exprY(TSh,Etq1,Etq2,Programa1,Programa2),
        {codifica(_,Etq2,Etq,Programa2,Programa,Op,0),!}.

exprY(TSh,Etqh,Etq,Programah,Programa) -->
        termino(TSh,Etqh,Etq,Programah,Programa),!.

opSuma('+') --> ['+'].
opSuma('-') --> ['-'].

termino(TSh,Etqh,Etq,Programah,Programa) --> 
        factor(TSh,Etqh,Etq1,Programah,Programa1),
        opProducto(Op),
        termino(TSh,Etq1,Etq2,Programa1,Programa2),
        {codifica(_,Etq2,Etq,Programa2,Programa,Op,_),!}.

termino(TSh,Etqh,Etq,Programah,Programa) -->
        factor(TSh,Etqh,Etq,Programah,Programa),!.

opProducto('*') --> ['*'].
opProducto('/') --> ['/'].
opProducto('%') --> ['%'].

factor(TSh,Etqh,Etq,Programah,Programa) -->
        ['('],exprY(TSh,Etqh,Etq,Programah,Programa),[')'],!.

factor(TSh,Etqh,Etq,Programah,Programa) -->
        operadorUnario(Op),
        factor(TSh,Etqh,Etq1,Programah,Programa1),
        {codifica(_,Etq1,Etq,Programa1,Programa,Op,0),!}.

factor(_TSh,Etqh,Etq,Programah,Programa) -->
        [N],
        {number(N),integer(N),codifica(_,Etqh,Etq,Programah,Programa,nument,N),!}.

factor(_TSh,Etqh,Etq,Programah,Programa) -->
        [N],
        {number(N),codifica(_,Etqh,Etq,Programah,Programa,numreal,N),!}.

factor(TSh,Etqh,Etq,Programah,Programa) -->
        descriptor(TSh,Etqh,Etq1,Programah,Programa1,Tipo),
        {codifica(Tipo,Etq1,Etq,Programa1,Programa,valor,_)}.

operadorUnario(neg) --> ['-'].
operadorUnario(abs) --> [abs].
operadorUnario(sqr) --> [sqr].

descriptor(TSh,Etqh,Etq,Programah,Programa,Tipo) --> 
        identificador(Lex),
        {busca(TSh,Lex,[Lex,Token,Tam,Off,TD]),
         variable(Token),
         codifica([Lex,Token,Tam,Off,TD],Etqh,Etq1,Programah,Programa1,id,0)},
        restoDescriptor(TSh,Etq1,Etq,Programa1,Programa,[Lex,Token,Tam,Off,TD],Tipo).

restoDescriptor(TSh,Etqh,Etq,Programah,Programa,[_Lex,puntero,_Tam,_Off,TD],Tipo) -->
        ['^'],
        {codifica(_,Etqh,Etq1,Programah,Programa1,puntero,0)},
        restoDescriptor(TSh,Etq1,Etq,Programa1,Programa,TD,Tipo).

restoDescriptor(TSh,Etqh,Etq,Programah,Programa,[_Lex,array,_Tam,_Off,TD],Tipo) -->
        ['['],[N],[']'],
        {integer(N),codifica(TD,Etqh,Etq1,Programah,Programa1,array,N)},
        restoDescriptor(TSh,Etq1,Etq,Programa1,Programa,TD,Tipo).

restoDescriptor(TSh,Etqh,Etq,Programah,Programa,[_Lex,registro,_Tam,_Off,TD],Tipo) -->
        ['.'],identificador(Lex),
        {busca(TD,Lex,[Lex,Token,TTam,TOff,TTD]),
         variable(Token),
         codifica([Lex,Token,TTam,TOff,TTD],Etqh,Etq1,Programah,Programa1,id,0),
         codifica(_,Etq1,Etq2,Programa1,Programa2,registro,0)},
        restoDescriptor(TSh,Etq2,Etq,Programa2,Programa,[Lex,Token,TTam,TOff,TTD],Tipo).

restoDescriptor(_TSh,Etqh,Etqh,Programah,Programah,Tipo,Tipo) -->
        [].

expresionRel(TSh,Etqh,Etq,Programah,Programa) -->
        exprY(TSh,Etqh,Etq1,Programah,Programa1),
        opRelacional(Op),
        exprY(TSh,Etq1,Etq2,Programa1,Programa2),
        {codifica(_,Etq2,Etq,Programa2,Programa,Op,0)}.

opRelacional('<') --> ['<'].
opRelacional('<=') --> ['<='].
opRelacional('>') --> ['>'].
opRelacional('>') --> ['>='].
opRelacional('<>') --> ['<>'].
opRelacional('=') --> ['='].
